package com.atguigu.lease.common.util;

import com.atguigu.lease.common.consts.StgyAdminConstant;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClaims;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.Map;

/**
 * 创建 解析jwt的token
 */
@Slf4j
public class JwtUtil {
    private static final String key = "124qwrwq4wqczrw2";

    public static String createToken(Map<String, String> params) {
        String token = Jwts.builder()
                //header： jwt的第一部分 头
                .setHeaderParam("alg", "HS256") //设置jwt的加密算法 HS256对称加密算法(加密解密使用同一个方式 同一个秘钥字符串)
                .setHeaderParam("typ", "JWT") //设置jwt的格式
                //payload： jwt的第二部分 载荷
                // jwt自己定义的载荷
                .setExpiration(
                        new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7))
                //                .setSubject("TEST-TOKEN") //设置jwt的主题：  前端根据这个判断 jwt的作用范围
                // 用户自定义的载荷：为了保持登录状态设置的 用户信息
                .claim(StgyAdminConstant.JWT_TOKEN_USER_ID, params.get(StgyAdminConstant.JWT_TOKEN_USER_ID))
                .claim(StgyAdminConstant.JWT_TOKEN_AVATAR_URL, params.get(StgyAdminConstant.JWT_TOKEN_AVATAR_URL))
                .claim(StgyAdminConstant.JWT_TOKEN_USER_NAME, params.get(StgyAdminConstant.JWT_TOKEN_USER_NAME))
                //sign： jwt的第三部分  签名
                //      作用：防止载荷数据被客户端篡改
                //  sign是使用 alg算法+ 服务器中配置的秘钥字符串 对载荷内存进行不可逆加密得到的一个字符串
                //  以后如果客户端修改了载荷内容，再次使用alg算法对载荷使用秘钥字符串加密得到的结果不一样
                .signWith(SignatureAlgorithm.HS256, key)
                //开始构建jwt字符串
                .compact();

        return token;
    }

    public static DefaultClaims parseToken(String token) {
        try {
            DefaultClaims body = (DefaultClaims) Jwts.parser()
                    .setSigningKey(key)
                    .parse(token)
                    .getBody();
            return body;
        } catch (ExpiredJwtException e) {
            log.error("登录状态已过期");
            throw new RuntimeException(e);
        } catch (MalformedJwtException e) {
            log.error("token格式错误");
            throw new RuntimeException(e);
        } catch (SignatureException e) {
            log.error("token被篡改");
            throw new RuntimeException(e);
        } catch (IllegalArgumentException e) {
            log.error("token的参数错误");
            throw new RuntimeException(e);
        }
    }
}